package com.terrynoya.fight.combat
{
	import com.terrynoya.common.util.DisplayUtil;
	import com.terrynoya.fight.animations.AnimationManager;
	import com.terrynoya.fight.animations.IAirInfo;
	import com.terrynoya.fight.char.Character;
	import com.terrynoya.fight.char.CharacterRender;
	import com.terrynoya.fight.char.Entity;
	import com.terrynoya.fight.char.ICharaterRender;
	import com.terrynoya.fight.emuns.PositionType;
	import com.terrynoya.fight.emuns.ProjectileState;
	import com.terrynoya.fight.system.camera.MCamera;
	import com.terrynoya.fight.util.Misc;
	import com.terrynoya.geom.MVector2D;
	
	import flash.display.Sprite;
	
	public class ProjectTile extends Entity
	{
		private var _data:ProjectileData;
		private var _creator:Character;
		private var _offsetCharacter:Character;
		private var _state:int;
		private var _posType:int;
		private var _gameTick:int;
		private var _hitPauseCountDown:int;
		private var _totalHits:int;
		private var _removeOnHit:Boolean;
		
		private var _view:Sprite;
		private var _render:ICharaterRender;
		
		public function ProjectTile(engine:FightEngine,creator:Character,data:ProjectileData)
		{
			super(engine);
			this._data = data;
			this._creator = creator;
			this._offsetCharacter = data.positionType == PositionType.P2 ? this._creator.getOpponent() : creator;
			this.animationManager = creator.animationManager.clone();
			this._render = creator.render;
			
			this._state = ProjectileState.Normal;
			this.currentFacing = creator.currentFacing;
			this.velocity = data.initialVelocity;
			this.acceleration = data.accelleration;
			this.removeOnHit = data.removeOnHit;
			
			this._view = new Sprite();
			this.engine.stage.characterLayer.addChild(this._view);
			this.setLocalAnimation(data.animationId,0);
		}
		
		public function get removeOnHit():Boolean
		{
			return _removeOnHit;
		}

		public function set removeOnHit(value:Boolean):void
		{
			_removeOnHit = value;
		}

		public function get totalHits():int
		{
			return _totalHits;
		}

		public function set totalHits(value:int):void
		{
			_totalHits = value;
		}

		public function get canAttack():Boolean 
		{
			if(this._state != ProjectileState.Normal)
			{
				return false;
			}
			if(this._hitPauseCountDown > 0)
			{
				return false;
			}
			return true;
		}
		
		public function get hitPauseCountDown():int
		{
			return _hitPauseCountDown;
		}

		public function set hitPauseCountDown(value:int):void
		{
			_hitPauseCountDown = value;
		}

		public function get creator():Character
		{
			return _creator;
		}

		public function get data():ProjectileData
		{
			return _data;
		}

		override public function updatePhysics():void
		{
			super.updatePhysics();
		}
		
		override public function draw():void
		{
			this._render.draw(this,this._view);
		}
		
		override public function updateState():void
		{
			super.updateState();
			if(this._gameTick == 0)
			{
				this.position = this.getStartLocation();
			}
			this._gameTick ++;
			
			if(this._hitPauseCountDown > 0)
			{
				this._hitPauseCountDown --;
			}
			
			this.collision = this.makeCollision();
			this.checkRemove();
		}
		
		private function checkRemove():void
		{
			var camera:MCamera = this.engine.camera;
			if(this._removeOnHit && this._totalHits > 0)
			{
				this.startRemoval();	
			}
			if(this.position.x > camera.right + this.data.stageEdgebound)
			{
				this.startRemoval();
			}
			if(this.position.x < camera.left - this.data.stageEdgebound)
			{
				this.startRemoval();
			}
		}
		
		override public function remove():void
		{
			DisplayUtil.removeFromParent(this._view);
		}
		
		override public function removeCheck():Boolean
		{
			return this._state == ProjectileState.Kill; 
		}
		
		private function startRemoval():void
		{
			this._state = ProjectileState.Kill;
		}
		
		private function getStartLocation():MVector2D
		{
			var facing:int = this._offsetCharacter.facing;
			var pos:MVector2D;
			switch(this._data.positionType)
			{
				case PositionType.P1:
				case PositionType.P2:
				{
					return Misc.getOffset(this._offsetCharacter.position,facing,this._data.creationOffset);
					break;
				}
			}
			return pos;
		}
	}
}